﻿using mozhi.smarterp.Finance.Enums;
using mozhi.smarterp.Finance.Finances.Repository;
using mozhi.smarterp.Finance.Querys;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Guids;

namespace mozhi.smarterp.Finance.Finances
{
    public class JournalNumberPrefixAppService : FinanceAppService, IJournalNumberPrefixAppService
    {
        private IJournalNumberPrefixRepository _repository;
        private IGuidGenerator _guidGenerator;
        public JournalNumberPrefixAppService(IJournalNumberPrefixRepository repository, IGuidGenerator guidGenerator,IServiceProvider serviceProvider)
            : base(serviceProvider)
        {
            _repository = repository;
            _guidGenerator = guidGenerator;
        }

        public async Task<JournalNumberPrefixDto> CreateAsync(JournalNumberPrefixCreateDto dto)
        {
            await ValidateDuplicate(dto.Name , null);

            var numberPrefix = new JournalNumberPrefix(_guidGenerator.Create(), dto.Code, dto.Name, dto.IsDefault);
            numberPrefix = await _repository.InsertAsync(numberPrefix);

            await _operationLogManager.LogAsync(ModuleCodeType.JournalNumberPrefix, Enums.OperationType.Add, numberPrefix, null);

            return ObjectMapper.Map<JournalNumberPrefix, JournalNumberPrefixDto>(numberPrefix);
        }

        public async Task<JournalNumberPrefixDto> UpdateAsync(JournalNumberPrefixUpdateDto dto)
        {
            var numberPrefix = await _repository.GetAsync(dto.Id);

            if (numberPrefix == null)
                throw new UserFriendlyException("凭证字不存在", "100000");

            var oldNumberPrefix = ObjectMapper.Map<JournalNumberPrefix, JournalNumberPrefixDto>(numberPrefix);

            await ValidateDuplicate(dto.Name , dto.Id);

            numberPrefix.Change(dto.Code, dto.Name, dto.IsDefault);

            numberPrefix = await _repository.UpdateAsync(numberPrefix);

            var newNumberPrefix = ObjectMapper.Map<JournalNumberPrefix, JournalNumberPrefixDto>(numberPrefix);

            await _operationLogManager.LogAsync(ModuleCodeType.JournalNumberPrefix, Enums.OperationType.Update, oldNumberPrefix, newNumberPrefix);

            return newNumberPrefix;
        }

        public async Task<bool> DeleteAsync(Guid id)
        {
            var numberPrefix = await _repository.GetAsync(id);

            if (numberPrefix == null)
                throw new UserFriendlyException("凭证字不存在", "100000");

            await CheckDataAssociation(id);

            await _operationLogManager.LogAsync(ModuleCodeType.JournalNumberPrefix, Enums.OperationType.Delete, numberPrefix, null);

            await _repository.DeleteAsync(id);

            return true;
        }

        public async Task<PagedResultDto<JournalNumberPrefixDto>> FindAsync(PageQuery query)
        {
            var entities = await _repository.FindAsync(query);

            var count = await _repository.GetCountAsync(query);

            var result = new PagedResultDto<JournalNumberPrefixDto>();

            var items = ObjectMapper.Map<List<JournalNumberPrefix>, List<JournalNumberPrefixDto>>(entities);

            result.TotalCount = count;
            result.Items = items;

            return result;
        }

        public async Task<JournalNumberPrefixDto> GetAsync(Guid id)
        {
            var word = await _repository.FindAsync(id, true);

            return ObjectMapper.Map<JournalNumberPrefix, JournalNumberPrefixDto>(word);
        }

        #region
        private async Task ValidateDuplicate(string name , Guid? currenctId)
        {
            var count = await _repository.GetCountAsync(new PageQuery() { Keyword = name ,ExclusionId = currenctId});

            if (count > 0)
                throw new UserFriendlyException("凭证字已存在存在", "100000");
        }
        #endregion
    }
}
